Howto define a static string array function parameter as call by reference

Hello,

I need to have a function where the first parmeter is a static string array, but it should be called as reference.

E.g. void function(string& myStaticArray[], ...)
{
string myTmpStaticArray[5];
myTmpStaticArray[0] = "0";
myTmpStaticArray[1] = "1";
myTmpStaticArray[2] = "2";
myTmpStaticArray[3] = "3";
myTmpStaticArray[4] = "4";
myStaticArray = myTmpStaticArray;
}

The problem:
when calling that function:

string myStaticArray[];
function(myStaticArray);
print sizeof myStaticArray "\n";

The size of myStaticArray is zero afterwards. Thus the call by reference does not work. Is there a special issue using static array for call by reference or does it not work in general for static arrays?

Many thanks in advance, Helko
Helko - Wed Jan 11 10:28:32 EST 2012

Re: Howto define a static string array function parameter as call by reference
rain_bow - Thu Jan 12 09:11:53 EST 2012

In the line " string myStaticArray[]; "
you defined the array as containing no elements.
This static feature can't be changed.

Re: Howto define a static string array function parameter as call by reference
SystemAdmin - Thu Jan 12 15:03:45 EST 2012

See this to see what you can and can't do:
 

string arrayNumbers[] = {"One", "Two", "Three", "Four", "Five"};
string arrayColors[] = {"Red", "Blue", "Green"};
 
 
string pointArraySomewhere(bool wantColors)[] {
    if (wantColors) {
        return arrayColors;
    } else {
        return arrayNumbers;
    }
}
 
//------------------------------------------------------------------------------
// Don't do this.
//
// The syntax is fine but the issue is you will be assigning
// a reference to array storage that will become garbage as soon as the
// function ends.
//
// You can assign arrays in this fashion if and only if the storage stays in
// scope.
//------------------------------------------------------------------------------
string loadMoods()[] {
    string moods[] = { "Normal", "DOORS Rage" };
    return moods;
}
 
 
void main() {
    int i;
    bool wantColors;
 
    string emptyArray[] = {}
    string arrayX[];
 
 
    wantColors = false;
    arrayX = emptyArray;
    arrayX = pointArraySomewhere(wantColors);
    print "sizeof(arrayX) = " (sizeof(arrayX)) "\n"
    for (i = 0; i < sizeof(arrayX); i++) {
        print("array[" (i) "] = " arrayX[i] "\n");
    }
 
    wantColors = true;
    arrayX = emptyArray;
    arrayX = pointArraySomewhere(wantColors);
    print "sizeof(arrayX) = " (sizeof(arrayX)) "\n"
    for (i = 0; i < sizeof(arrayX); i++) {
        print("array[" (i) "] = " arrayX[i] "\n");
    }
 
    arrayX = emptyArray;
    arrayX = loadMoods();
    print "sizeof(arrayX) = " (sizeof(arrayX)) "\n"
    // If the below will either crash DOORS or not consistently execute
    for (i = 0; i < sizeof(arrayX); i++) {
        print("array[" (i) "] = " arrayX[i] "\n");
    }
}
 
main();

 

 

EXECUTION:


sizeof(arrayX) = 5
array[0] = One
array[1] = Two
array[2] = Three
array[3] = Four
array[4] = Five
sizeof(arrayX) = 3
array[0] = Red
array[1] = Blue
array[2] = Green
sizeof(arrayX) = 2
-R-E- DXL: <C:\Program Files\IBM\Rational\DOORS\9.3/lib/dxl/addins/user/_showEnumeratedTypes.dxl:205> array bounds exceeded (0)
Backtrace:
<C:\Program Files\IBM\Rational\DOORS\9.3/lib/dxl/addins/user/_showEnumeratedTypes.dxl:209>
-I- DXL: execution halted

 

 

Re: Howto define a static string array function parameter as call by reference
Mathias Mamsch - Thu Jan 12 18:30:16 EST 2012

As Hal already demonstrated it is not a problem of the size of the array, but a problem of assignment:

int ar1[] = {1,2,3}
int ar2[] = {1,2,3,4}
int ar[] 
 
ar = ar2; print ar[3]  // prints 4
ar = ar1; print ar[2]  // prints 3

The above works. Obviously we can reassign an array. However when we put the assignment to a function, then it does NOT work:

int globalArray[] = {1,2,3}
int ar[]
 
void func (int &y[]) { y = globalArray }
 
func (ar); print ar[2] // array bounds exceeded (2)


The reason is as simple as stupid: int &y[] is actually an array containing integer references, not a reference to an array of integers! That is it is parsed "(int &) ar[]". Therefore if we put it like this it works again:

int globalArray[] = {1,2,3}
int ar[]
 
void func (int (&y)[]) { y = globalArray }
 
func (ar); print ar[2] // prints 3


However it is not a good idea, to return an array from a function. Arrays will live inside the function they are declared. That means that myTmpStaticArray is valid inside your function, but it is invalidated as soon as the function leaves. The mean thing is, that it will seem to work at the first glance, but kick your ass later, when you allocate more stack space. Example:

int globalArray[] = {1,2,3}
int ar[]
 
void func (int (&y)[]) { int temp[3] = {4,5,6}; y = temp}
 
func (ar); print ar[2]  // prints 6


The above seems to work. But it does only work, because the memory of the temp array, that has already been freed, has not been overwritten by something else yet. Lets proove that:

int globalArray[] = {1,2,3}
int ar[]
 
void func (int (&y)[]) { int temp[3] = {4,5,6}; y = temp }
 
int useSomeStack(int nr) { if (nr < 1000) return useSomeStack(nr+1) else return nr }
 
func (ar);       // get the temporary array
useSomeStack(0); // use some stack after returning the temp array, before accessing its contents
// print ar[2]   // comment me in to crash the program


Hope that clears matters up. Regards, Mathias

 

 

Re: Howto define a static string array function parameter as call by reference
Helko - Fri Jan 13 07:59:48 EST 2012

Hello,

thanks a lot to all of you!

Helko